<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>

//显式声明变量
//【示例1】执行下面代码，将会提示语法错误。
"use strict";
v = 1; 						// 报错，v未声明
for(i = 0; i < 2; i++) { 	// 报错，i未声明
} 

//静态绑定

//禁止使用with语句

　　"use strict";
　　var v = 1;
　　with (o){ 				// 语法错误 
 　　　　v = 2;
　　}

//创设eval作用域

　　"use strict";
　　var x = 2;
　　console.info(eval("var x = 5; x")); 	// 5
　　console.info(x); 						// 2
//另外，任何使用'eval'的操作都会被禁止，例如，下面用法都是非法的。
'use strict'
var obj = {}
var eval = 3
obj.eval = 1
obj.a = eval
for (var eval in obj) {}
function eval() {}
function func(eval) {}
var func = new Function('eval')

//增强的安全措施
//禁止this关键字指向全局对象
　　function f(){
　　　　return !this;
　　} 　　// 返回false，因为"this"指向全局对象，"!this"就是false
　　function f(){ 
　　　　"use strict";
　　　　return !this;
　　} // 返回true，因为在严格模式下，this的值为undefined，所以"!this"为true。

//【示例3】使用构造函数时，如果忘了加new语句，this不再指向全局对象，而是报错。
　　function f(){ 
　　　　"use strict";
　　　　this.a = 1;
　　};
　　f();							// 报错，this未定义

//禁止在函数内部遍历调用栈
//【示例4】caller、callee和arguments的调用行为都被禁用。
　　function f1(){
　　　　"use strict";
　　　　f1.caller; 					// 报错
　　　　f1.arguments; 				// 报错
　　}
　　f1();


//禁止删除变量
//在严格模式下无法删除变量。只有configurable设置为true的对象属性，才能被删除。
//【示例5】
　　"use strict";
　　var x;
　　delete x; 						// 语法错误
　　var o = Object.create(null, 'x', {
　　　　　　value: 1,
　　　　　　configurable: true
　　});
　　delete o.x; 					// 删除成功


//显式报错
//在正常模式下，对一个对象的只读属性进行赋值，不会报错，只会默默地失败。严格式下，将报错。
//【示例6】
　　"use strict";
　　var o = {};
　　Object.defineProperty(o, "v", { value: 1, writable: false });
　　o.v = 2; 						// 报错
//严格模式下，对一个使用getter方法读取的属性进行赋值，会报错。
　　"use strict";
　　var o = {
　　　　get v() { return 1; } 
　　};
　　o.v = 2; 						// 报错

//严格模式下，对禁止扩展的对象添加新属性，会报错。
　　"use strict";
　　var o = {};
　　Object.preventExtensions(o);
　　o.v = 1; // 报错

//严格模式下，删除一个不可删除的属性，会报错。
　　"use strict";
　　delete Object.prototype; 		// 报错


//重名错误

　　"use strict";
　　var o = {
　　　　p: 1,
　　　　p: 2
　　}; 								// 语法错误


　　"use strict";
　　function f(a, a, b) { 			// 语法错误 
　　　　return ; 
　　}

// 禁止八进制表示法
　　"use strict";
　　var n = 0100; 					// 语法错误


//arguments对象的限制

//不允许对arguments赋值

　　"use strict";
　　arguments++; // 语法错误
　　var obj = { set p(arguments) { }};	// 语法错误
　　try { } catch (arguments) { } 		// 语法错误
　　function arguments() { } 			// 语法错误
　　var f = new Function("arguments", "'use strict'; return 17;"); // 语法错误
//arguments不再追踪参数的变化
　　function f(a) {
　　　　a = 2;
　　　　return [a, arguments[0]];
　　}
　　f(1); 							// 正常模式为[2,2]
　　function f(a) {
　　　　"use strict"; 
　　　　a = 2;
　　　　return [a, arguments[0]];
　　}
　　f(1); 							// 严格模式为[2,1]

//禁止使用arguments.callee
　　"use strict";
　　var f = function() { return arguments.callee; };
　　f(); 							// 报错

//函数必须声明在顶层
　　"use strict";
　　if (true) {
　　　　function f() { } 			// 语法错误
　　}
　　for (var i = 0; i < 5; i++) {
　　　　function f2() { } 			// 语法错误
　　}

//保留字
　　function package(protected) { 	// 语法错误
　　　　"use strict";
　　　　var implements; 				// 语法错误
　　}


//动态绑定
'use strict'
function func() {
    console.log(typeof this)
}
func.call('abcd') 					// string
func.apply(1)     					// number 


'use strict'
function func() {
    console.log(this)
}
func.call(undefined) 				// undefined
func.call(null)      				// null 

//【示例12】下面代码在非严格模式中输出都是window（或global）。
'use strict'
function func() {
    console.log(this)
}
var f1 = func.bind(null)
var f2 = func.bind(undefined)
f1() 								// null
f2() 								// undefined 



</script>
</head>
<body>

</body>
</html>
